package com.ruoyi.swla2.controller;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.swla2.model.FreezeDataQueryModel;
import com.ruoyi.swla2.model.ZoneJoinModel;
import com.ruoyi.swla2.service.IZoneJoinService;
import com.ruoyi.swla2.util.CustomExcelUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.swla2.domain.TerminalsFreeze;
import com.ruoyi.swla2.service.ITerminalsFreezeService;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 大日冻结数据Controller
 *
 * @author gdqt
 * @date 2023-08-30
 */
@RestController
@RequestMapping("/swla2/terminalsFreeze")
public class TerminalsFreezeController extends BaseController {
    @Autowired
    private ITerminalsFreezeService terminalsFreezeService;

    @Autowired
    private IZoneJoinService zoneJoinService;

    @PreAuthorize("@ss.hasPermi('swla2:freezeDfq:list')")
    @GetMapping("/listByQueryModel")
    public AjaxResult listByQueryModel(FreezeDataQueryModel model) {
        ZoneJoinModel zoneJoinModel = new ZoneJoinModel();
        zoneJoinModel.setTerminalMark(1);
        List<ZoneJoinModel> zoneJoinModelList = zoneJoinService.getZoneJoinTerminals(zoneJoinModel);
        return AjaxResult.success(this.doGetByQueryModel(zoneJoinModelList, model));
    }

    /**
     * 查询大日冻结数据列表
     */
    @PreAuthorize("@ss.hasPermi('swla2:terminalsFreeze:list')")
    @GetMapping("/list")
    public TableDataInfo list(TerminalsFreeze terminalsFreeze) {
        startPage();
        List<TerminalsFreeze> list = terminalsFreezeService.selectTerminalsFreezeList(terminalsFreeze);
        return getDataTable(list);
    }

    /**
     * 导出大日冻结数据列表
     */
    @PreAuthorize("@ss.hasPermi('swla2:terminalsFreeze:export')")
    @Log(title = "大日冻结数据", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, FreezeDataQueryModel model) {
        ZoneJoinModel zoneJoinModel = new ZoneJoinModel();
        zoneJoinModel.setTerminalMark(1);
        List<ZoneJoinModel> zoneJoinModelList = zoneJoinService.getZoneJoinTerminals(zoneJoinModel);
        List<Map<String, Object>> dataMapList = this.doGetByQueryModel(zoneJoinModelList, model);
        String name = model.getDataType().equals("flow") ? "流量报表" : "压力报表";
        CustomExcelUtils.createExcel(dataMapList, name, name, response);
    }

    /**
     * 获取大日冻结数据详细信息
     */
    @PreAuthorize("@ss.hasPermi('swla2:terminalsFreeze:query')")
    @GetMapping(value = "/{tenantId}")
    public AjaxResult getInfo(@PathVariable("tenantId") String tenantId) {
        return success(terminalsFreezeService.selectTerminalsFreezeByTenantId(tenantId));
    }

    /**
     * 新增大日冻结数据
     */
    @PreAuthorize("@ss.hasPermi('swla2:terminalsFreeze:add')")
    @Log(title = "大日冻结数据", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TerminalsFreeze terminalsFreeze) {
        terminalsFreeze.setTenantId(this.getTenantId());
        return toAjax(terminalsFreezeService.insertTerminalsFreeze(terminalsFreeze));
    }

    /**
     * 修改大日冻结数据
     */
    @PreAuthorize("@ss.hasPermi('swla2:terminalsFreeze:edit')")
    @Log(title = "大日冻结数据", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TerminalsFreeze terminalsFreeze) {
        return toAjax(terminalsFreezeService.updateTerminalsFreeze(terminalsFreeze));
    }

    /**
     * 删除大日冻结数据
     */
    @PreAuthorize("@ss.hasPermi('swla2:terminalsFreeze:remove')")
    @Log(title = "大日冻结数据", businessType = BusinessType.DELETE)
    @DeleteMapping("/{tenantIds}")
    public AjaxResult remove(@PathVariable String[] tenantIds) {
        return toAjax(terminalsFreezeService.deleteTerminalsFreezeByTenantIds(tenantIds));
    }

    private List<Map<String, Object>> doGetByQueryModel(List<ZoneJoinModel> zoneJoinModelList, FreezeDataQueryModel model) {
        this.checkAndSetDate(model);
        List<TerminalsFreeze> freezeList = terminalsFreezeService.selectTerminalsFreezeByQueryModel(model);
        freezeList.removeIf(item -> StrUtil.isEmpty(item.getTerminalName()));

        List<ZoneJoinModel> queryModelList = new ArrayList<>(zoneJoinModelList);
        queryModelList.removeIf(item -> !item.getAreaId().equals(model.getAreaId()));
        queryModelList.sort(Comparator.comparing(ZoneJoinModel::getUsed, Comparator.reverseOrder()));
        LinkedHashMap<String, String> terminalUsedNameMap = new LinkedHashMap<>();
        LinkedHashMap<String, String> terminalNameMap = new LinkedHashMap<>();
        queryModelList.forEach(item -> {
            terminalUsedNameMap.put(item.getTerminalId(), item.getUsedName());
            terminalNameMap.put(item.getTerminalId(), item.getTerminalName());
        });

        Map<String, List<TerminalsFreeze>> dataMap = freezeList.stream().collect(Collectors.groupingBy(TerminalsFreeze::getTerminalID));
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        terminalUsedNameMap.forEach((key, value) -> {
            List<TerminalsFreeze> tmpDataList = dataMap.get(key);
            if (CollUtil.isNotEmpty(tmpDataList)) {
                LinkedHashMap<String, Object> tmpMap = new LinkedHashMap<>();
                tmpMap.put("设备名称", terminalNameMap.get(key));
                tmpMap.put("设备用途", terminalUsedNameMap.get(key));
                double min, max, avg;
                if (model.getDataType().equals("flow")) {
                    min = tmpDataList.stream().mapToDouble(item -> item.getCumulativeFlow().doubleValue()).min().getAsDouble();
                    max = tmpDataList.stream().mapToDouble(item -> item.getCumulativeFlow().doubleValue()).max().getAsDouble();
                    avg = tmpDataList.stream().mapToDouble(item -> item.getCumulativeFlow().doubleValue()).average().getAsDouble();
                } else {
                    min = tmpDataList.stream().mapToDouble(item -> item.getAvgPipePressure() == null ? 0D : item.getAvgPipePressure().doubleValue()).min().getAsDouble();
                    max = tmpDataList.stream().mapToDouble(item -> item.getAvgPipePressure() == null ? 0D : item.getAvgPipePressure().doubleValue()).max().getAsDouble();
                    avg = tmpDataList.stream().mapToDouble(item -> item.getAvgPipePressure() == null ? 0D : item.getAvgPipePressure().doubleValue()).average().getAsDouble();
                }
                BigDecimal b = new BigDecimal(avg);
                avg = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                tmpDataList.forEach(item -> {
                    BigDecimal tmpValue = model.getDataType().equals("flow") ? item.getCumulativeFlow() : item.getAvgPipePressure();
                    tmpMap.put(item.getFreezeTime(), (tmpValue == null ? 0D : tmpValue.doubleValue()) + "," + item.getMark());
                });
                tmpMap.put("最小值", min);
                tmpMap.put("最大值", max);
                tmpMap.put("平均值", avg);
                dataMapList.add(tmpMap);
            }
        });
        return dataMapList;
    }

    private void checkAndSetDate(FreezeDataQueryModel model) {
        if (model.getFrozenType().equals("day")) {
            LocalDate yesterday = LocalDate.now().minusDays(1L);
            if (StrUtil.isEmpty(model.getEndDate())) {
                model.setEndDate(yesterday.toString());
            }
            if (StrUtil.isEmpty(model.getStartDate())) {
                model.setStartDate(yesterday.minusDays(14L).toString());
            }
        } else {
            LocalDate lastMonth = LocalDate.now().minusDays(1L);
            if (StrUtil.isEmpty(model.getEndDate())) {
                model.setEndDate(lastMonth.toString().substring(0, 7));
            }
            if (StrUtil.isEmpty(model.getStartDate())) {
                model.setStartDate(lastMonth.minusMonths(6L).toString().substring(0, 7));
            }
        }
    }
}
